home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Collections: Franz PD
/
Franz PD Disk #324 (1994-04)(Rhein-Sieg-Soft).zip
/
Franz PD Disk #324 (1994-04)(Rhein-Sieg-Soft).adf
/
VideoText3.5
/
source
/
jobs.p
< prev
next >
Wrap
Text File
|
1994-04-01
|
11KB
|
297 lines
UNIT jobs; {$project vt }
{ Job-Verwaltung zum Programm VideoText }
INTERFACE; FROM vt USES global,sys,bildschirm,datei,cct,pagelist;
PROCEDURE sleep;
PROCEDURE wakeup;
PROCEDURE handle_queue;
PROCEDURE handle_jobs;
PROCEDURE attempt_input(job: Integer);
PROCEDURE add_job(entry: Str80);
PROCEDURE getconfig;
{ ---------------------------------------------------------------------- }
IMPLEMENTATION;
{$opt b-}
CONST SUBTITLE = $0040; { C6 }
SERMAG = $0800; { C11 }
VAR bedtime: zeiteintrag;
PROCEDURE uhrzeit(VAR zeit: zeiteintrag);
BEGIN
telltime(zeit.tage,zeit.min,zeit.tics);
END;
PROCEDURE sleep;
{ wird vor Unterbrechung der Hauptschleife (z. B. durch Prozedur displayhelp) }
{ aufgerufen }
BEGIN
uhrzeit(bedtime);
END;
PROCEDURE wakeup;
{ Verhindert in Zusammenarbeit mit sleep, daß Zeiten, während derer der }
{ VT-Decoder gar nicht abgefragt wird, zum Löschen von Jobs wegen }
{ Zeitüberschreitung führen. }
VAR delta: zeiteintrag;
j: Integer;
BEGIN
uhrzeit(delta);
sub_time(bedtime,delta);
FOR j := 0 TO maxactive-1 DO
add_time(delta,activejobs[j].lastaction);
END;
PROCEDURE handle_queue;
{ Wird aus der Hauptschleife heraus aufgerufen. Verwaltet das Aufrücken }
{ wartender Jobs und das Entfernen überalterter Seitenanforderungen. }
{ Ein Job besteht zunächst aus einer Seitennummer pg und einer Unterseiten- }
{ nummer sp, plus zusätzlichen Informationen, sobald er aktiv ist. }
VAR i, j: Integer;
jetzt: zeiteintrag;
BEGIN
{ Prüfen, ob Jobs aus der Warteschlange in die aktiven Plätze nachrücken }
{ können, erkennbar an 'aktiven' Jobs mit pg=0. }
FOR j := 0 to maxactive-1 DO
IF (activejobs[j].pg=0) AND (queued>0) THEN BEGIN
{ freie Empfangseinheit mit wartendem Job belegen }
WITH activejobs[j] DO BEGIN
pg := queue[1].pg; sp := queue[1].sp;
sp_count := 0; sp_max := 0;
holen := False; erledigt := False; ist_UT := 0;
FOR i := 0 TO anzsubpage DO sp_check[i] := False;
uhrzeit(lastaction);
anfordern(j,pg,sp,'!!!');
END;
{ Warteschlange aufrücken: }
Dec(queued);
FOR i := 1 TO queued DO queue[i] := queue[i+1];
{ Auswahlzeiger des Benutzers dem Aufrücken entsprechend nachführen: }
IF thisjob=-1 THEN thisjob := j
ELSE IF thisjob<0 THEN Inc(thisjob);
IF thisjob>=0 THEN BEGIN
aktspeicher := thisjob; display_select(aktspeicher); END;
redraw_queue(-1);
END;
{ Prüfen, ob ein Job wegen Zeitüberschreitung gestrichen werden kann. }
{ Wenn der Job allerdings so lange wartet, weil er sich auf eine einzelne }
{ Unterseite bezieht, ist ihm verziehen und er wird lediglich ans Ende der }
{ Warteschlange gesetzt. Und für Jobs, die sich auf Untertitel beziehen, }
{ findet eine Prüfung auf Zeitüberschreitung gar nicht erst statt. }
uhrzeit(jetzt);
FOR j := 0 TO maxactive-1 DO WITH activejobs[j] DO
IF (pg<>0) AND (diff_time(lastaction,jetzt) > 50*maxwait)
AND (ist_UT=0) THEN
IF activejobs[j].sp = 0 THEN BEGIN { einfache Seitennummer streichen }
activejobs[j].pg := 0;
sperren(j);
redraw_queue(j);
END ELSE { Unterseitenanforderung nur hintenanstellen }
IF queued>0 THEN BEGIN
IF queued<qlen THEN BEGIN
Inc(queued);
queue[queued].pg := activejobs[j].pg;
queue[queued].sp := activejobs[j].sp;
END;
activejobs[j].pg := 0;
sperren(j);
redraw_queue(-1);
END;
END;
PROCEDURE handle_jobs;
{ Überprüft, ob in einem der Empfangskreise eine Seite eingetroffen ist, und }
{ wenn ja, ob sie aufgrund ihrer Unterseitennummer überhaupt eingelesen }
{ werden muß. Es wird auch entschieden, ob der Job durch die eingetroffene }
{ Seite erledigt ist. Einlesen der Seite geschieht an anderer Stelle, da nach }
{ Eintreffen der Kopfzeile erst eine Weile gewartet werden muß. }
VAR j: Integer;
dummy: p_onepage;
BEGIN
{ Schauen, ob irgendwo das Eintreffen einer Kopfzeile gemeldet wurde: }
FOR j := 0 TO maxactive-1 DO WITH activejobs[j] DO
IF (pg>0) AND NOT holen THEN IF seite_da(j) THEN BEGIN
{ write(#7); }
New(dummy);
uhrzeit(lastaction);
getpage(j,dummy,false); { *nur* Status und Seitennummer holen }
{ *** Schauen, ob die Seite eingelesen werden muß. Gründe, weswegen }
{ man eine Seite evtl. nicht haben will: }
{ 1.: Unterseite wurde bereits eingelesen. }
{ (Bei zu großen Unterseitennummern kann das nur über ein etwas }
{ armseliges Hilfskriterium festgestellt werden.) }
IF (dummy^.sp<=anzsubpage) THEN holen := NOT sp_check[dummy^.sp]
ELSE holen := (dummy^.sp>sp_max);
{ Und für UT-Seiten ist "bereits eingelesen" überhaupt kein }
{ Hinderungsgrund: }
IF ist_UT<>0 THEN holen := True;
{ 2.: Nur eine Unterseite war angefordert, und zwar nicht diese. }
{ Das dürfte allerdings kaum vorkommen, da der CCT ausdrücklich auf }
{ die eine Unterseite programmiert wurde. }
IF (sp>0) THEN
holen := (dummy^.sp=sp)
{ *** Unterseitenverwaltung aktualisieren: }
IF holen THEN BEGIN
Inc(sp_count);
IF (dummy^.sp<=anzsubpage) THEN sp_check[dummy^.sp] := True;
IF dummy^.sp>sp_max THEN sp_max := dummy^.sp;
akt_sp := dummy^.sp;
redraw_queue(j);
END;
{ *** Prüfen, ob der Job durch die eingetroffene Seite erledigt ist. }
{ Das geht z. B. durch Unterseite 0 (= einzige Unterseite), auf }
{ keinen Fall aber durch eine Unterseite mit der bislang höchsten }
{ Nummer. }
IF sp_check[0] THEN
erledigt := sp_count>sp_max
ELSE IF dummy^.sp<sp_max THEN
erledigt := sp_count=sp_max;
{ Auch möglich: die einzig geforderte Unterseite ist da. }
IF (sp>0) AND holen THEN
erledigt := True;
{ *** Schauen, ob magazinserielle oder -gemischte Übertragung vorliegt }
{ und danach die Wartezeit festlegen: }
IF (dummy^.cbits AND SERMAG)=0 THEN
wartezeit := shuffle ELSE wartezeit := burst;
IF NOT holen THEN
anfordern(j,pg,sp,'!!!'); { Suche geht weiter, PBLF setzen }
Dispose(dummy);
END;
END;
PROCEDURE attempt_input{(job: Integer)};
{ Das Einlesen geschieht in einem zweiten Schritt, da nach Eintreffen der }
{ Kopfzeile erst eine Weile gewartet werden muß. Evtl. wird die Seite auch }
{ gleich ausgegeben: auf dem Bildschirm, falls <thisjob> auf den zugehörigen }
{ Job zeigt; in die Protokolldatei, falls es eine Untertitelseite ist und }
{ Protokollierung erwünscht war. }
{ Erledigte Jobs werden auch gestrichen, sobald keine zu holende Seite mehr }
{ aussteht. }
{ Kriterium für 'erledigt': }
{ Ein Job mit sp<>0 ist erledigt, sobald die eine angeforderte Unterseite }
{ da ist. Ein Job mit sp=0 ist erst dann erledigt, wenn alle seine }
{ Unterseiten eingelesen wurden. Ein Job, der sich auf eine Untertitelseite }
{ bezieht (Flag C5), ist niemals erledigt und muß anderweitig entfernt }
{ werden. }
VAR dummy,seite: p_onepage;
jetzt: zeiteintrag;
BEGIN
{ Prüfen, ob die Wartezeit für eine einzulesende Seite um ist: }
WITH activejobs[job] DO
IF (pg>0) AND holen THEN BEGIN
uhrzeit(jetzt);
IF diff_time(lastaction,jetzt) >= wartezeit THEN BEGIN
{ Seite einlesen: }
busy_pointer;
{ Ist bereits eine alte Version dieser Seite in der Liste, die dann }
{ lediglich überschrieben werden müßte? }
seite := hunt_in_list(pg,akt_sp,True);
IF seite=Nil THEN BEGIN
New(seite);
getpage(job,seite,True);
ins_to_list(seite);
normal_pointer;
redraw_list;
END ELSE BEGIN
getpage(job,seite,True);
normal_pointer;
END;
IF seite=thispage THEN writepage(seite,True);
{ notieren, ob das eine Untertitelseite war: }
ist_UT := ist_UT SHR 1; { Bits altern lassen }
IF (seite^.cbits AND SUBTITLE)<>0 THEN ist_UT := ist_UT OR $04;
IF protokoll AND (ist_UT<>0) THEN BEGIN
mainline;
Write('Untertitelseite ',seite^.pg,' ...');
IF savebox(seite,outputname,True) THEN
Write(' gespeichert.')
ELSE BEGIN
mainline; Write(#155'33mDateifehler - sorry!');
END;
END;
holen := False; { Wichtig !!! }
anfordern(job,pg,sp,'!!!'); { um PBLF wieder zu setzen }
END;
END;
{ Erledigten Job löschen, außer er bezieht sich auf Untertitel }
WITH activejobs[job] DO
IF (pg>0) AND erledigt AND NOT holen THEN
IF (ist_UT<>0) THEN BEGIN { nicht löschen }
sp_check[0] := False; sp_count := 0; redraw_queue(job);
END ELSE BEGIN { löschen }
pg := 0; redraw_queue(job); sperren(job);
END;
END;
PROCEDURE add_job{(entry: Str80)};
{ Eine Eingabe, die eine Seitennummer darstellt (oder auch nicht), in die }
{ Warteschlange einzureihen versuchen. }
var j,ok,page,subpage: integer;
s: str80;
begin
j := pos('/',entry);
if j > 0 then begin
s := copy(entry,1,j-1);
val(s,page,ok);
s := copy(entry,j+1,length(entry)-j);
val(s,subpage,ok);
end else begin
val(entry,page,ok);
subpage := 0;
end;
if (ok=0) AND (page>=100) AND (page<900) AND (queued<qlen) then begin
Inc(queued);
queue[queued].pg := page; queue[queued].sp := subpage;
end;
end;
PROCEDURE getconfig;
VAR datei: text;
sender, zeile: Str80;
is_job, found, anything: boolean;
t: integer;
BEGIN
anfordern(0,100,0,'***');
t := 50; { max. 1 sec warten! }
REPEAT Delay(1); Dec(t) UNTIL seite_da(0) or (t=0);
gethead(0,sender);
WITH activejobs[0] DO
IF pg>0 THEN anfordern(0,pg,sp,'!!!') ELSE sperren(0);
Reset(datei,'VT.config');
IF IOResult<>0 THEN BEGIN
Reset(datei,'s:VT.config');
IF IOResult<>0 THEN BEGIN
Write(#155'33m"VT.config" nicht gefunden!');
Exit;
END;
END;
found := False; anything := False;
WHILE NOT EoF(datei) DO BEGIN
ReadLn(datei,zeile);
is_job := True;
FOR t := 1 TO Length(zeile) DO
IF NOT (zeile[t] IN ['0'..'9','/']) THEN is_job := False;
IF is_job THEN BEGIN
IF found THEN add_job(zeile);
IF queued=maxactive THEN handle_queue; { Jobs evtl. aufrücken }
END ELSE BEGIN
found := (Pos(zeile,sender)>0) AND (zeile<>'');
IF found THEN BEGIN
mainline; Write('hole Seitenauswahl f}r "',zeile,'"');
anything := true;
END;
END;
END;
IF NOT anything THEN Write('unbekannter Sender: "',Copy(sender,5,10),'"');
Close(datei);
redraw_queue(-1);
END;
BEGIN { Initialisierungen }
END.